38장 브라우저의 렌더링 과정


Untitled 32.png|Untitled 32.png

전체적인 브라우저의 렌더링 과정이다

  1. HTML, CSS, JS, 이미지 등 렌더링에 필요한 리소스 요청하고 서버로부터 응답받음.
  2. 렌더링 엔진은 서버로부터 응답 받은 html css을 파싱해서 DOM 과 CSSOM 을 생성하고 이들을 결합하여 렌더 트리 생성
  3. 자바스크립트 엔진은 서버로부터 응답된 JS를 파싱하여 AST 생성하고 바이트 코드로 변환하여 실행. 이때 JS는 DOM API를 통해서 DOM이나 CSSOM을 변경할 수 있다. 변경된 것들은 다시 렌더 트리로 결합
  4. 렌더 트리를 기반으로 HTML 요소의 레이아웃을 계산하고 브라우저 화면에 페인팅.

요청과 응답

주소창에 URL입력하면 URL의 호스트 이름이 DNS통해서 IP 주소로 변환되고 서버에게 요청을 전송
Untitled 1 18.png|Untitled 1 18.png

브라우저의 렌더링 엔진이 html을 파싱하다가 외부 리소스를 로드하는 태그를 만나면 html 파싱 일시 중단하고 해당 리소스파일을 서버에 요청.

HTTP 1.1 과 HTTP 2.0

HTTP/1.1 은 커넥션 당 하나의 요청과 응답만 처리할 수 있다. 리소스 요청과 응답이 개별적으로 이루어진다. 이처럼 리소스의 동시 전송이 불가능한 구조라 리소스 개수 많아지면 응답시간이 길어진다.

HTTP/2 는 커넥션당 여러개의 요청과 응답이 가능하다. 즉, 다중 요청/응답이 가능.
Untitled 2 15.png|Untitled 2 15.png|300

Untitled 3 11.png|Untitled 3 11.png|300

HTML 파싱과 DOM 생성

HTML 문서를 브라우저에 시각적인 픽셀로 렌더링하려면 HTML 문서를 브라우저가 이해할 수 있는 자료구조로 변환하여 메모리에 저장해야한다.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <ul>
      <li id="apple">Apple</li>
      <li id="banana">Banana</li>
      <li id="orange">Orange</li>
    </ul>
    <script src="app.js"></script>
  </body>
</html>

렌더링 엔진은 다음과 같은 html을 파싱해서 브라우저가 이해할 수 있는 자료구조인 DOM을 생성한다.

Untitled 4 8.png|Untitled 4 8.png

  1. 서버의 HTML 파일이 브라우저의 요청에 의해 응답. 2진수 바이트 형태로 응답
  2. 응답된 바이트 형태의 HTML문서를 인코딩하여 문자열로 변환
  3. 문자열로 변환된 HTML문서를 읽어서 토큰들로 분해
  4. 토큰들을 객체로 변환하여 노드들을 생성. 토큰 내용에 따라 노드의 종류가 달라진다.
  5. HTML 요소 간에는 중첩관계에 의해 부자 관계가 형성되고 이를 반영하여 모든 노드들을 트리 자료구조로 구성

CSS 파싱과 CSSOM 생성

렌더링 엔진 HTML 한줄 씩 파싱해 나가면서 DOM 생성하다가, CSS 로드하는 link 태그나 style 태그 만나면 DOM 생성 일시 중단.

CSS를 html과 동일한 파싱과정 거쳐며 해석해서 CSSOM 생성.

다시 중단된 HTML 파싱 해나간다.
Untitled 5 7.png|Untitled 5 7.png

렌더 트리 생성

생성한 DOM 과 CSSOM 을 렌더트리로 결합.

렌더트리는 렌더링을 위한 트리 구조의 자료구조이다. 렌더트리에는 브라우저 화면에 렌더링되는 노드만으로 구성된다.

Untitled 6 6.png|Untitled 6 6.png

만들어진 render tree로 layout을 계산하고 브라우저에 픽셀을 렌더링하는 painting 처리에 입력
Untitled 7 6.png|Untitled 7 6.png
이러한 렌더링 과정은 노드의 변화가 있을 때 다시 반복된다.

리렌더링은 overhead가 크기 때문에 되도록 빈번하게 발생하지 않게 해야한다.

자바스크립트 파싱과 실행

파싱하다가 script 코드를 파싱하기 위해 자바스크립트 엔진에 제어권을 넘긴다.

자바스크립트 엔진은 자바스크립트를 해석해서 AST(추상적 구문 트리)를 생성하고 이를 기반으로 인터프리터가 실행할 수 있는 중간코드인 바이트 코드를 생성해서 실행한다.

Untitled 8 6.png|Untitled 8 6.png

리플로우와 리페인트

자바스크립트 코드에 DOM, CSSOM 가 변경될 경우, 다시 렌더 트리로 결합하고 변경된 렌더 트리를 기반으로 레이아웃과 페인트 과정을 다시 거쳐서 렌더링 한다.

이를 리플로우, 리페인트 라고 한다.

Untitled 9 5.png|Untitled 9 5.png

자바스크립트 파싱에 의한 HTML 파싱 중단

렌더링 엔진과 자바스크립트 엔진은 병렬적으로 파싱을 실행하지 않고 직렬적으로 파싱을 수행한다.
→ 자바스크립트 코드의 위치에 따라서 문제를 발생시킬 수도 있고 로딩시간을 좌우한다.
⇒ body 요소의 가장 아래에 자바스크립트를 위치 시켜라.

script 태그의 asyncs/defer 어트리 뷰트

async와 defer 어트리뷰트는 src 어트리뷰트를 통해 외부 자바스크립트 파일을 로드하는 경우에만 사용할 수 있다.
외부 자바스크립트 파일의 로드를 비동기적으로 진행시킨다.

async 어트리 뷰트
파일의 로드가 완료된 직후 실행
Untitled 10 4.png|Untitled 10 4.png

defer 어트리 뷰트
HTML 파싱이 완료된 직후 실행
Untitled 11 3.png|Untitled 11 3.png

reference